﻿<h1>Arrays, Slices and Maps in Go</h1>

<p>
Strictly speaking, there are three kinds of first-class citizen
container types in Go, array, slice and map.
Sometimes, strings and channels can also be viewed as container types,
but this article will not touch the two kinds of types.
All container types talked about in the current article are
arrays, slices and maps.
</p>

<p>
There are many container related details in Go.
This article will list them one by one.
</p>

<h3>Simple Overview of Container Types and Values</h3>

<div>
<p>
Each value of the three kinds of types is used to
store a collection of element values.
The types of all the elements stored in a container value are identical.
The identical type is called the element type of
(the container type of) the container value.
</p>

<p>
Each element in a container has an associated key.
An element value can be accessed or modified through its associated key.
The key types of map types must be
<a href="type-system-overview.html#types-not-support-comparison">comparable types</a>.
The key types of array and slice types are all the built-in type <code>int</code>.
The keys of the elements of an array or slice are non-negative integers
which mark the positions of these elements in the array or slice.
The non-negative integer keys are often called indexes.
</p>

<p>
Each container value has a length property,
which indicates how many elements are stored in that container.
The valid range of the integer keys of an array or slice value is
from zero (inclusive) to the length (exclusive) of the array or slice.
For each value of a map type, the key values of that map value can be
an arbitrary value of the key type of the map type.
</p>

<p>
There are also many differences between the three kinds of container types.
Most of the differences originate from the differences between
the value memory layouts of the three kinds of types.
From the last article, <a href="value-part.html">value parts</a>,
we learned that an array value consists of only one direct part,
however a slice or map value may have an underlying part,
which is referenced by the direct part of the slice or map value.
</p>

<p>
Elements of an array or a slice are both stored
contiguously in a continuous memory segment.
For an array, the continuous memory segment
hosts the direct part of the array.
For a slice, the continuous memory segment
hosts the underlying indirect part of the slice.
The map implementation of the standard Go compiler/runtime
adopts the hashtable algorithm.
So all elements of a map are also stored in an underlying
continuous memory segment, but they may be not contiguous.
There may be many holes (gaps) within the continuous memory segment.
Another common map implementation algorithm is the binary tree algorithm.
Whatever algorithm is used, the keys associated with the elements of a map
are also stored in (the underlying parts of) the map.
</p>

We can access an element through its key.
The time complexities of element accesses on all container values
are all <code><i>O</i>(1)</code>,
though, generally map element accesses are several times
slower than array and slice element accesses.
But maps have two advantages over arrays and slices:
<ul>
<li>
	the key types of maps can be any comparable types.
</li>
<li>
	maps consume much less memory than arrays and slices with a large quantity of sparse indexes (integer keys).
</li>
</ul>

<p>
From the last article, we have learned that the underlying parts of a value
will not get copied when the value is copied.
In other words, if a value has underlying parts,
a copy of the value will share the underlying parts with the value.
This is the root reason of many behavior differences
between array and slice/map values.
These behavior differences will be introduced below.
</p>

</div>

<h3>Literal Representations of Non-defined Container Types</h3>

<div>
The literal representations of the three kinds of non-defined container types:
<ul>
<li>array types: <code>[N]T</code></li>
<li>slice types: <code>[]T</code></li>
<li>map types: <code>map[K]T</code></li>
</ul>

where
<ul>
<li>
	<code>T</code> is an arbitrary type.
	It specifies the element type of a container type.
	Only values of the specified element type can be stored
	as element values of values of the container type.
</li>
<li>
	<code>N</code> must be a non-negative integer constant.
	It specifies the number of elements stored in any value of an array type,
	and it can be called the length of the array type.
	This means the length of an array type is the inherent part of the array type.
	For example, <code>[5]int</code> and <code>[8]int</code>
	are two distinct array types.
</li>
<li>
	<code>K</code> is an arbitrary comparable type.
	It specifies the key type of a map type.
	Most types in Go are comparable, incomparable types are
	<a href="type-system-overview.html#types-not-support-comparison">listed here</a>.
</li>
</ul>

Here are some container type literal representation examples:
<pre class="line-numbers must-line-numbers"><code class="language-go">const Size = 32

type Person struct {
	name string
	age  int
}

/* Array types */

[5]string
[Size]int
// Element type is a slice type: []byte
[16][]byte
// Element type is a struct type: Person
[100]Person

/* Slice types *

[]bool
[]int64
// Element type is a map type: map[int]bool
[]map[int]bool
// Element type is a pointer type: *int
[]*int

/* Map types */

map[string]int
map[int]bool
// Element type is an array type: [6]string
map[int16][6]string
// Element type is a slice type: []string
map[bool][]string
// Element type is a pointer type: *int8,
// and key type is a struct type.
map[struct{x int}]*int8
</code></pre>

<p>
</p>

<p>
The <a href="type-system-overview.html#value-size">sizes</a> of all slice types are the same.
The sizes of all map types are also the same.
The size of an array type depends on its length and the size of its element type.
The size of a zero-length array type or an array type
with a zero-size element type is zero.
</p>

</div>

<a class="anchor" id="value-literals"></a>
<h3>Container Value Literals</h3>

<div>
Like struct values, container values can also be represented
with composite literals, <code>T{...}</code>, where <code>T</code> denotes container type
(except the zero values of slice and map types).
Here are some examples:
<pre class="line-numbers"><code class="language-go">// An array value containing four bool values.
[4]bool{false, true, true, false}

// A slice value which contains three words.
[]string{"break", "continue", "fallthrough"}

// A map value containing some key-value pairs.
map[string]int{"C": 1972, "Python": 1991, "Go": 2009}
</code></pre>

<p>
Each key-element pair between the braces of a map composite literal is also called an entry.
</p>

There are several variants for array and slice composite literals:
<pre class="line-numbers"><code class="language-go">
// The followings slice composite literals
// are equivalent to each other.
[]string{"break", "continue", "fallthrough"}
[]string{0: "break", 1: "continue", 2: "fallthrough"}
[]string{2: "fallthrough", 1: "continue", 0: "break"}
[]string{2: "fallthrough", 0: "break", "continue"}

// The followings array composite literals
// are equivalent to each other.
[4]bool{false, true, true, false}
[4]bool{0: false, 1: true, 2: true, 3: false}
[4]bool{1: true, true}
[4]bool{2: true, 1: true}
[...]bool{false, true, true, false}
[...]bool{3: false, 1: true, true}
</code></pre>

<p>
In the last two literals, the <code>...</code>s mean we want to let compilers
deduce the lengths for the corresponding array values.
</p>

<!--
<p>
The element values in a container composite literal must
be assignable to the corresponding container element type.
The key values in a map composite literal must
be assignable to the corresponding map key type.
</p>
-->

From the above examples, we know that element indexes (keys) are optional
in array and slice composite literals. In an array or slice composite literal,
<ul>
<li>
	if an index is present,
	it is not needed to be a typed value of the key type <code>int</code>,
	but it must be a non-negative constant representable as a value of type <code>int</code>.
	And if it is typed, its type must be a basic integer type.
</li>
<li>
	<b>an element which index is absent uses the previous element's index plus one as its index.</b>
</li>
<li>
	if the index of the first element is absent, its index is zero.
</li>
</ul>

<p>
The keys in a map literal can be absent, they can be non-constants.
</p>

<pre class="line-numbers"><code class="language-go">var a uint = 1
var _ = map[uint]int {a : 123} // okay

// The following two lines fail to compile,
// for "a" is not a constant key/index.
var _ = []int{a: 100}  // error
var _ = [5]int{a: 100} // error
</code></pre>

<p>
</p>

<p>
Constant keys in one specific composite literal <a href="details.html#constant-keys-in-composite-literals">can't be duplicate</a>.
</p>

</div>

<h3>Literal Representations of Zero Values of Container Types</h3>

<p>
Like structs, the zero value of an array type <code>A</code> can be represented
with the composite literal <code>A{}</code>.
For example, the zero value of type <code>[100]int</code>
can be denoted as <code>[100]int{}</code>.
All elements stored in the zero value of an array type
are zero values of the element type of the array type.
</p>

<p>
Like pointer types, zero values of all slice and map types are represented
with the predeclared <code>nil</code>.
</p>

<p>
BTW, there are some other kinds of types whose zero values are also represented by <code>nil</code>,
including later to be introduced function, channel and interface types.
</p>

<p>
When an array variable is declared without being specified an initial value,
memory has been allocated for the elements of the zero array value.
The memory for the elements of a nil slice or map value has not been allocated yet.
</p>

<p>
Please note, <code>[]T{}</code> represents a blank slice value (with zero elements)
of slice type <code>[]T</code>, it is different from <code>[]T(nil)</code>.
The same situation is for <code>map[K]T{}</code> and <code>map[K]T(nil)</code>.
</p>

<a class="anchor" id="take-composite-literal-address"></a>
<h3>Composite Literals Are Unaddressable but Can Be Taken Addresses</h3>

<div>
<p>
We have learned that
<a href="struct.html#take-composite-literal-address">struct composite literals
can be taken addresses directly</a> before.
Container composite literals have no exceptions here.
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	pm := &map[string]int{"C": 1972, "Go": 2009}
	ps := &[]string{"break", "continue"}
	pa := &[...]bool{false, true, true, false}
	fmt.Printf("%T\n", pm) // *map[string]int
	fmt.Printf("%T\n", ps) // *[]string
	fmt.Printf("%T\n", pa) // *[4]bool
}
</code></pre>
<p>
</p>
</div>

<a class="anchor" id="composite-literal-simplification"></a>
<h3>Nested Composite Literals Can Be Simplified</h3>

<div>
<p>
If a composite literal nested many other composite literals, then those nested
composited literals can simplified to the form <code>{...}</code>.
</p>

For example, the slice value literal

<pre class="line-numbers"><code class="language-go">
// A slice value of a type whose element type is
// *[4]byte. The element type is a pointer type
// whose base type is [4]byte. The base type is
// an array type whose element type is "byte".
var heads = []*[4]byte{
	&[4]byte{'P', 'N', 'G', ' '},
	&[4]byte{'G', 'I', 'F', ' '},
	&[4]byte{'J', 'P', 'E', 'G'},
}
</code></pre>

can be simplified to

<pre class="line-numbers"><code class="language-go">var heads = []*[4]byte{
	{'P', 'N', 'G', ' '},
	{'G', 'I', 'F', ' '},
	{'J', 'P', 'E', 'G'},
}
</code></pre>

<p>
</p>

The array value literal in the following example
<pre class="line-numbers"><code class="language-go">type language struct {
	name string
	year int
}

var _ = [...]language{
	language{"C", 1972},
	language{"Python", 1991},
	language{"Go", 2009},
}
</code></pre>

can be simplified to

<pre class="line-numbers"><code class="language-go">var _ = [...]language{
	{"C", 1972},
	{"Python", 1991},
	{"Go", 2009},
}
</code></pre>

<p>
</p>

And the map value literal in the following example
<pre class="line-numbers"><code class="language-go">type LangCategory struct {
	dynamic bool
	strong  bool
}

// A value of map type whose key type is
// a struct type and whose element type
// is another map type "map[string]int".
var _ = map[LangCategory]map[string]int{
	LangCategory{true, true}: map[string]int{
		"Python": 1991,
		"Erlang": 1986,
	},
	LangCategory{true, false}: map[string]int{
		"JavaScript": 1995,
	},
	LangCategory{false, true}: map[string]int{
		"Go":   2009,
		"Rust": 2010,
	},
	LangCategory{false, false}: map[string]int{
		"C": 1972,
	},
}
</code></pre>

can be simplified to

<pre class="line-numbers"><code class="language-go">var _ = map[LangCategory]map[string]int{
	{true, true}: {
		"Python": 1991,
		"Erlang": 1986,
	},
	{true, false}: {
		"JavaScript": 1995,
	},
	{false, true}: {
		"Go":   2009,
		"Rust": 2010,
	},
	{false, false}: {
		"C": 1972,
	},
}
</code></pre>

<p>
Please notes, in the above several examples, the comma following the last item
in each composite literal can't be omitted.
Please read <a href="line-break-rules.html">the line break rules in Go</a>
for more information later.
</p>

</div>

<a class="anchor" id="comparison"></a>
<h3>Compare Container Values</h3>

<p>
As which has mentioned in the article
<a href="type-system-overview.html#types-not-support-comparison">overview of
Go type system</a>, map and slice types are incomparable types.
So map and slice types can't be used as map key types.
</p>

<p>
Although a slice or map value can't be compared with another slice or map value
(or itself), it can be compared to the bare untyped <code>nil</code> identifier
to check whether or not the slice or map value is a zero value.
</p>

<p>
Most array types are comparable,
except the ones whose element types are incomparable types.
</p>

<p>
When comparing two array values, each pair of the corresponding elements will be compared.
The two array values are equal only if all of their corresponding elements are equal.
</p>

<div>
Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	var a [16]byte
	var s []int
	var m map[string]int

	fmt.Println(a == a)   // true
	fmt.Println(m == nil) // true
	fmt.Println(s == nil) // true
	fmt.Println(nil == map[string]int{}) // false
	fmt.Println(nil == []int{})          // false

	// The following lines fail to compile.
	/*
	_ = m == m
	_ = s == s
	_ = m == map[string]int(nil)
	_ = s == []int(nil)
	var x [16][]int
	_ = x == x
	var y [16]map[int]bool
	_ = y == y
	*/
}
</code></pre>
<p>
</p>
</div>

<a class="anchor" id="cap-len"></a>
<h3>Check Lengths and Capacities of Container Values</h3>

<p>
Besides the length property, each container value also has a capacity property.
The capacity of an array is always equal to the length of the array.
The capacity of a non-nil map can be viewed as unlimited.
So, in practice, only capacities of slice values are meaningful.
The capacity of a slice is always equal to or larger than the length of the slice.
The meaning of slice capacities will be explained in the section after next.
</p>

<p>
We can use the built-in <code>len</code> function to get the length of
a container value, and use the built-in <code>cap</code> function to
get the capacity of a container value.
Each of the two functions returns an <code>int</code> result
(the result <a href="https://github.com/golang/go/issues/31795">might be changed to an untyped integer value</a> since a later Go version).
As the capacity of any map value is unlimited,
the built-in <code>cap</code> function doesn't apply to map values.
</p>

<p>
The length and capacity of an array value can never change.
The lengths and capacities of all values of an array type always equal to the length of the array type.
The length and capacity of a slice value may change at run time.
So slices can be viewed as dynamic arrays.
Slices are much more flexible than arrays
and are used more popularly than arrays in practice.
</p>

<div>
Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	var a [5]int
	fmt.Println(len(a), cap(a)) // 5 5
	var s []int
	fmt.Println(len(s), cap(s)) // 0 0
	s, s2 := []int{2, 3, 5}, []bool{}
	fmt.Println(len(s), cap(s))   // 3 3
	fmt.Println(len(s2), cap(s2)) // 0 0
	var m map[int]bool
	fmt.Println(len(m)) // 0
	m, m2 := map[int]bool{1: true, 0: false}, map[int]int{}
	fmt.Println(len(m), len(m2)) // 2 0
}
</code></pre>

<p>
The length and capacity of each slice shown in the above specified example value are equal.
This is not true for every slice value.
We will use some slices whose respective lengths and capacities are not equal in the following sections.
</p>
</div>

<a class="anchor" id="element-access"></a>
<h3>Retrieve and Modify Container Elements</h3>

<div>
<p>
The element associated to key <code>k</code> stored in a container value
<code>v</code> is represented with the element indexing syntax form <code>v[k]</code>.

</p>

For a use of <code>v[k]</code>, assume <code>v</code> is an array or slice,
<ul>
<li>
	if <code>k</code> is a constant, then it must satisfy
	<a href="#value-literals">the requirements described above</a>
	for the indexes in container composite literals.
	In addition, if <code>v</code> is an array, the
	<code>k</code> must be smaller than the length of the array.
</li>
<li>
	if <code>k</code> is a non-constant value, it must be a value of any basic integer type.
	In addition, it must be larger than or equal to zero and smaller than <code>len(v)</code>,
	otherwise, a run-time panic will occur.
</li>
<li>
	if <code>v</code> is a nil slice,
	a run-time panic will occur.
</li>
</ul>

For a use of <code>v[k]</code>, assume <code>v</code> is a map,
then <code>k</code> must be assignable to values of
the element type of the map type, and
<ul>
<li>
	if <code>k</code> is an interface value whose dynamic type is incomparable,
	a panic will occur at run time.
</li>
<li>
	if <code>v[k]</code> is used as a destination value in an assignment and <code>v</code> is a nil map,
	a panic will occur at run time.
</li>
<li>
	if <code>v[k]</code> is used to retrieve the element value corresponding key <code>k</code> in map <code>v</code>,
	then no panics will occur, even if <code>v</code> is a nil map.
	(Assume the evaluation of <code>k</code> will not panic.)
</li>
<li>
	if <code>v[k]</code> is used to retrieve the element value corresponding key <code>k</code> in map <code>v</code>,
	and the map <code>v</code> doesn't contain an entry with
	key <code>k</code>, <code>v[k]</code> results a zero value of
	the element type of the corresponding map type of <code>v</code>.
	Generally, <code>v[k]</code> is viewed as a single-value
	expression. However, when <code>v[k]</code> is used as the only source
	value expression in an assignment, it can be viewed as a multi-value
	expression and result a second optional untyped boolean value,
	which indicates whether or not the map <code>v</code> contains an entry
	with key <code>k</code>.
</li>
</ul>

An example of container element accesses and modifications:
<pre class="line-numbers must-line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	a := [3]int{-1, 0, 1}
	s := []bool{true, false}
	m := map[string]int{"abc": 123, "xyz": 789}
	fmt.Println (a[2], s[1], m["abc"])    // retrieve
	a[2], s[1], m["abc"] = 999, true, 567 // modify
	fmt.Println (a[2], s[1], m["abc"])    // retrieve

	n, present := m["hello"]
	fmt.Println(n, present, m["hello"]) // 0 false 0
	n, present = m["abc"]
	fmt.Println(n, present, m["abc"]) // 567 true 567
	m = nil
	fmt.Println(m["abc"]) // 0

	// The two lines fail to compile.
	/*
	_ = a[3]  // index 3 out of bounds
	_ = s[-1] // index must be non-negative
	*/

	// Each of the following lines can cause a panic.
	_ = a[n]         // panic: index out of range
	_ = s[n]         // panic: index out of range
	m["hello"] = 555 // panic: assign to entry in nil map
}
</code></pre>

<p>
</p>
</div>

<h3>Recall the Internal Structure Definition of Slice Types</h3>

<div>
To understand slice types and values better and explain slices easier,
we need to have an impression on the internal structure of slice types.
From the last article, <a href="value-part.html">value parts</a>,
we learned that the internal structure of slice types
defined by the standard Go compiler/runtime is like
<pre class="line-numbers must-line-numbers"><code class="language-go">type _slice struct {
	elements unsafe.Pointer // referencing underlying elements
	len      int            // length
	cap      int            // capacity
}
</code></pre>

<p>
The internal structure definitions used by other compilers/runtimes
implementations may be not the exact same but would be similar.
The following explanations are based on the official slice implementation.
</p>

<p>
The above shown internal structure explains the memory layouts of
the direct parts of slice values.
The <code>len</code> field of the direct part of a slice indicates
the length of the slice, and the <code>cap</code> field indicates
the capacity of the slice.
The following picture depicts one possible memory layout of a slice value.

<div class="text-center">
<img src="res/slice-internal.png" alt="slice internal"></img>
</div>
</p>

<p>
Although the underlying memory segment which hosts the elements of a slice
may be very large, the slice may be only aware of a sub-segment of the
memory segment. For example, in the above picture, the slice is only
aware of the middle grey sub-segment of the whole memory segment.
</p>

<p>
For the slice depicted in the above picture, the elements from
index <code>len</code> to index <code>cap</code> (exclusive)
don't belong to the elements of the slice.
They are just some redundant element slots for the depicted slice,
but they may be effective elements of other slices or another array.
</p>

<p>
The next section will explain how to append elements to a base slice and yield
a new slice by using the built-in <code>append</code> function.
The result slice of an <code>append</code> function call may share starting
elements with the base slice or not, depending on the capacity (and length)
of the base slice and how many elements are appended.
</p>

When the slice is used as the base slice in an <code>append</code> function call,
<ul>
<li>
	if the number of appended elements is larger than the number of
	the redundant element slots of the base slice,
	a new underlying memory segment will be allocated for the result slice,
	thus the result slice and the base slice will not share any elements.
</li>
<li>
	otherwise, no new underlying memory segments will be allocated
	for the result slice, and the elements of the base slice also
	belong to the elements of the result slice.
	In other words, the two slices share some elements and all of
	their elements are hosted on the same underlying memory segment.
</li>
</ul>

<p>
The section after next will show a picture which describes both of
the two possible cases in appending slice elements.
</p>

<p>
There are more routes which lead to the elements of two slices
are hosted on the same underlying memory segment.
Such as assignments and the below to be introduced subslice operations.
</p>

<p>
Note, generally, we can't modify the three fields of a slice value individually,
except through the <a href="#modify-slice-length-and-capacity">reflection</a>
and <a href="unsafe.html">unsafe</a> ways.
In other words, generally, to modify a slice value,
its three fields must be modified together.
Generally, this is achieved by assigning another slice value
(of the same slice type) to the slice which needs to be modified.
</p>

</div>

<a class="anchor" id="assignment"></a>
<h3>Container Assignments</h3>

<div>

<p>
If a map is assigned to another map, then the two maps will
share all (underlying) elements.
Appending elements into (or deleting elements from) one map
will reflect on the other map.
</p>

<p>
Like map assignments, if a slice is assigned to another slice,
they will share all (underlying) elements.
Their respective lengths and capacities equal to each other.
However, if the length/capacity of one slice changes later,
the change will not reflect on the other slice.
</p>

<p>
When an array is assigned to another array,
all the elements are copied from the source one to the destination one.
The two arrays don't share any elements.
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	m0 := map[int]int{0:7, 1:8, 2:9}
	m1 := m0
	m1[0] = 2
	fmt.Println(m0, m1) // map[0:2 1:8 2:9] map[0:2 1:8 2:9]

	s0 := []int{7, 8, 9}
	s1 := s0
	s1[0] = 2
	fmt.Println(s0, s1) // [2 8 9] [2 8 9]

	a0 := [...]int{7, 8, 9}
	a1 := a0
	a1[0] = 2
	fmt.Println(a0, a1) // [7 8 9] [2 8 9]
}
</code></pre>

<p>
</p>
</div>

<a class="anchor" id="element-addition-deletion"></a>
<h3>Append and Delete Container Elements</h3>

<div>
The syntax of appending a key-element pair (an entry)
to a map is the same as the syntax of modifying a map element.
For example, for a non-nil map value <code>m</code>,
the following line
<pre class="disable-line-numbers111"><code class="language-go">m[k] = e
</code></pre>

<p>
put the key-element pair <code>(k, e)</code> into the map <code>m</code>
if <code>m</code> doesn't contain an entry with key <code>k</code>,
or modify the element value associated with <code>k</code>
if <code>m</code> contains an entry with key <code>k</code>.
</p>

<!--
<p>
The underlying continuous memory segment of a map might need reallocated
to hold more and more elements if a new entry is put into the map.
</p>
-->

There is a built-in <code>delete</code> function
which is used to delete an entry from a map.
For example, the following line will delete the entry with key
<code>k</code> from the map <code>m</code>.
If the map <code>m</code> doesn't contain an entry with key <code>k</code>,
it is a no-op, no panics will occur,
even if <code>m</code> is a nil map.
<pre class="disable-line-numbers111"><code class="language-go">delete(m, k)
</code></pre>

<p>
</p>

An example shows how to append (put) entries to and delete entries from maps:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	m := map[string]int{"Go": 2007}
	m["C"] = 1972     // append
	m["Java"] = 1995  // append
	fmt.Println(m)    // map[C:1972 Go:2007 Java:1995]
	m["Go"] = 2009    // modify
	delete(m, "Java") // delete
	fmt.Println(m)    // map[C:1972 Go:2009]
}
</code></pre>

<p>
Please note, before Go 1.12, the entry print order of a map is unspecified.
</p>

<p>
Array elements can neither be appended nor deleted,
though elements of addressable arrays can be modified.
</p>

<p>
We can use the built-in <code>append</code> function
to append multiple elements into a base slice and result a new slice.
The result new slice contains the elements of the base slice and the appended elements.
Please note, the base slice is not modified by the <code>append</code> function call.
Surely, if we expect (and often in practice), we can assign the result slice
to the base slice to modify the base slice.
</p>

<p>
There is not a built-in way to delete an element from a slice.
We must use the <code>append</code> function and
the subslice feature introduced below together to achieve this goal.
Slice element deletions and insertions will be demoed in the below
<a href="#slice-manipulations">more slice manipulations</a> section.
Here, the following example only shows how to use the <code>append</code> function.
</p>

An example showing how to use the <code>append</code> function:

<pre class="line-numbers must-line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	s0 := []int{2, 3, 5}
	fmt.Println(s0, cap(s0)) // [2 3 5] 3
	s1 := append(s0, 7)      // append one element
	fmt.Println(s1, cap(s1)) // [2 3 5 7] 6
	s2 := append(s1, 11, 13) // append two elements
	fmt.Println(s2, cap(s2)) // [2 3 5 7 11 13] 6
	s3 := append(s0)         // <=> s3 := s0
	fmt.Println(s3, cap(s3)) // [2 3 5] 3
	s4 := append(s0, s0...)  // double s0 as s4
	fmt.Println(s4, cap(s4)) // [2 3 5 2 3 5] 6

	s0[0], s1[0] = 99, 789
	fmt.Println(s2[0], s3[0], s4[0]) // 789 99 2
}
</code></pre>

<p>
</p>

<p>
Note, the built-in <code>append</code> function is a
<a href="function.html#variadic-function">variadic function</a>.
It has two parameters, the second one is a
<a href="function.html#variadic-parameter">variadic parameter</a>.
</p>

<p>
Variadic functions will be explained in the article after next.
Currently, we only need to know that there are two manners to pass variadic arguments.
In the above example, line <i>8</i>, line <i>10</i> and line <i>12</i> use
one manner and line <i>14</i> uses the other manner.
For the former manner, we can pass zero or more element values as the variadic arguments.
For the latter manner, we must pass a slice as the only variadic argument and
which must be followed by three dots <code>...</code>.
We can learn how to call variadic functions from the <a href="function.html#variadic-call">the article after next</a>.
</p>

In the above example, line <i>14</i> is equivalent to

<pre class="disable-line-numbers111"><code class="language-go">	s4 := append(s0, s0[0], s0[1], s0[2])
</code></pre>
<p>
</p>

line <i>8</i> is equivalent to

<pre class="disable-line-numbers111"><code class="language-go">	s1 := append(s0, []int{7}...)
</code></pre>
<p>
</p>

and line <i>10</i> is equivalent to

<pre class="disable-line-numbers111"><code class="language-go">	s2 := append(s1, []int{11, 13}...)
</code></pre>

<p>
</p>

<p>
For the three-dot <code>...</code> manner, the <code>append</code> function doesn't
require the variadic argument must be a slice with the same type as the first
slice argument, but their element types must be identical.
In other words, the two argument slices must share the same
<a href="type-system-overview.html#underlying-type">underlying type</a>.
</p>

In the above program,
<ul>
<li>
	the <code>append</code> call at line <i>8</i> will allocate a new
	underlying memory segment for slice <code>s1</code>,
	for slice <code>s0</code> doesn't have enough redundant element slots
	to store the new appended element. The same situation is for the
	<code>append</code> call at line <i>14</i>.
</li>
<li>
	the <code>append</code> call at line <i>10</i> will not allocate a new
	underlying memory segment for slice <code>s2</code>,
	for slice <code>s1</code> has enough redundant element slots
	to store the new appended elements.
</li>
</ul>

<p>
So, <code>s1</code> and <code>s2</code> share some elements,
<code>s0</code> and <code>s3</code> share all elements,
and <code>s4</code> doesn't share elements with others.
The following picture depicted the statuses of these slices
at the end of the above program.

<div class="text-center">
<img src="res/slice-append.png" alt="slice statuses"></img>
</div>
</p>

<p>
Please note that, when an <code>append</code> call allocate a new underlying memory segment
for the result slice, the capacity of the result slice is compiler dependent.
For the standard Go compiler, if the capacity of the base slice is small,
the capacity of the result slice will be at least the double of the base slice,
to avoid allocating underlying memory segments frequently when the result slice is
used as the base slices in later possible <code>append</code> calls.
</p>

As mentioned above, we can assign the result slice to the base slice
in an <code>append</code> call to append elements into the base slice.
For example,

<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	var s = append([]string(nil), "array", "slice")
	fmt.Println(s)      // [array slice]
	fmt.Println(cap(s)) // 2
	s = append(s, "map")
	fmt.Println(s)      // [array slice map]
	fmt.Println(cap(s)) // 4
	s = append(s, "channel")
	fmt.Println(s)      // [array slice map channel]
	fmt.Println(cap(s)) // 4
}
</code></pre>

<p>
</p>

<p>
Up to now (Go 1.13), the first argument of an <code>append</code> function
call can't be an untyped <code>nil</code>.
</p>

</div>

<a class="anchor" id="make"></a>
<h3>Create Slices and Maps With the Built-in <code>make</code> Function</h3>

<div>
<p>
Besides using composite literals to create map and slice values,
we can also use the built-in <code>make</code> function to create map and slice values.
The built-in <code>make</code> function can't be used to create array values.
</p>

<p><i>
BTW, the built-in <code>make</code> function can also be used to create
channels, which will be explained in the article
<a href="channel.html">channels in Go</a> later.
</i></p>

Assume <code>M</code> is a map type and <code>n</code> is non-negative integer,
we can use the following two forms to create new maps of type <code>M</code>.
<pre class="line-numbers"><code class="language-go">make(M, n)
make(M)
</code></pre>

<p>
The first form creates a new empty map which is allocated with enough space to
hold at least <code>n</code> entries without reallocating memory again.
The second form only takes one argument,
in which case a new empty map with enough space to
hold a small number of entries without reallocating memory again.
The small number is compiler dependent.
</p>

Assume <code>S</code> is a slice type, <code>length</code> and
<code>capacity</code> are two non-negative integers,
<code>length</code> is not larger than <code>capacity</code>,
we can use the following two forms to create new slices of type <code>S</code>.

<pre class="line-numbers"><code class="language-go">make(S, length, capacity)
make(S, length)
</code></pre>

<p>
The first form creates a new slice with the specified length and capacity.
The second form only takes two arguments, in which case the capacity of
the new created slice is the same as its length.
</p>

<p>
All the elements in the result slice of a <code>make</code> function call
are initialized as the zero value (of the slice element type).
</p>

An example on how to use the built-in <code>make</code> function
to create maps and slices:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	// Make new maps.
	fmt.Println(make(map[string]int)) // map[]
	m := make(map[string]int, 3)
	fmt.Println(m, len(m)) // map[] 0
	m["C"] = 1972
	m["Go"] = 2009
	fmt.Println(m, len(m)) // map[C:1972 Go:2009] 2

	// Make new slices.
	s := make([]int, 3, 5)
	fmt.Println(s, len(s), cap(s)) // [0 0 0] 3 5
	s = make([]int, 2)
	fmt.Println(s, len(s), cap(s)) // [0 0] 2 2
}
</code></pre>

<p>
</p>

</div>

<a class="anchor" id="new"></a>
<h3>Allocate Containers With the Built-in <code>new</code> Function</h3>

<div>
<p>
From the article <a href="pointer.html">pointers in Go</a>, we learned that
we can also call the built-in <code>new</code> function to allocate
a value of any type and get a pointer which references the allocated value.
The allocated value is a zero value of its type.
For this reason, it is a nonsense to use <code>new</code> function to
create map and slice values.
</p>

<p>
It is not totally a nonsense to allocate a zero value of an array type
with the built-in <code>new</code> function.
However, it is seldom to do this in practice,
for it is more convenient to use composite literals to allocate arrays.
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	m := *new(map[string]int)   // <=> var m map[string]int
	fmt.Println(m == nil)       // true
	s := *new([]int)            // <=> var s []int
	fmt.Println(s == nil)       // true
	a := *new([5]bool)          // <=> var a [5]bool
	fmt.Println(a == [5]bool{}) // true
}
</code></pre>

<p>
</p>

</div>

<a class="anchor" id="addressability"></a>
<h3>Addressability of Container Elements</h3>

<div>
Following are some facts about the addressabilities of container elements.
<ul>
<li>
	Elements of addressable array values are also addressable.
	Elements of unaddressable array values are also unaddressable.
	The reason is each array value only consists of one direct part.
</li>
<li>
	Elements of any slice value are always addressable,
	whether or not that slice value is addressable.
	This is because the elements of a slice are stored in
	the underlying value part of the slice and the underlying part
	is always hosted on an allocated memory segment.
</li>
<li>
	Elements of map values are always unaddressable.
	Please read <a href="unofficial-faq.html#maps-are-unaddressable">this FAQ item</a> for reasons.
</li>
</ul>

For example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	a := [5]int{2, 3, 5, 7}
	s := make([]bool, 2)
	pa2, ps1 := &a[2], &s[1]
	fmt.Println(*pa2, *ps1) // 5 false
	a[2], s[1] = 99, true
	fmt.Println(*pa2, *ps1) // 99 true
	ps0 := &[]string{"Go", "C"}[0]
	fmt.Println(*ps0) // Go

	m := map[int]bool{1: true}
	_ = m
	// The following lines fail to compile.
	/*
	_ = &[3]int{2, 3, 5}[0]
	_ = &map[int]bool{1: true}[1]
	_ = &m[1]
	*/
}
</code></pre>

<p>
</p>

<p>
Unlike most other unaddressable values, which direct parts can not be modified,
the direct part of a map element values can be modified,
but can only be modified (overwritten) as a whole.
For most kinds of element types, this is not a big issue.
However, if the element type of map type is an array type or struct type,
things become some counter-intuitive.
</p>

From the last article, <a href="value-part.html">value parts</a>, we learned
that each of struct and array values only consists of one direct part.
So
<ul>
<li>
	if the element type of a map is a struct type,
	we can not individually modify each field of an element (which is a struct) of the map.
</li>
<li>
	if the element type of a map is an array type,
	we can not individually modify each element of an element
	(which is an array) of the map.
</li>
</ul>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	type T struct{age int}
	mt := map[string]T{}
	mt["John"] = T{age: 29} // modify it as a whole
	ma := map[int][5]int{}
	ma[1] = [5]int{1: 789} // modify it as a whole

	// The following two lines fail to compile,
	// for map elements can be modified partially.
	/*
	ma[1][1] = 123      // error
	mt["John"].age = 30 // error
	*/

	// Accesses are okay.
	fmt.Println(ma[1][1])       // 789
	fmt.Println(mt["John"].age) // 29
}
</code></pre>

<p>
</p>

To make any expected modification work in the above example,
the corresponding map element should be saved in a temporary variable firstly,
then the temporary variable is modified as needed, in the end
the corresponding map element is overwritten by the temporary variable.
For example,

<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	type T struct{age int}
	mt := map[string]T{}
	mt["John"] = T{age: 29}
	ma := map[int][5]int{}
	ma[1] = [5]int{1: 789}

	t := mt["John"] // a temporary copy
	t.age = 30
	mt["John"] = t // overwrite it back

	a := ma[1] // a temporary copy
	a[1] = 123
	ma[1] = a // overwrite it back

	fmt.Println(ma[1][1], mt["John"].age) // 123 30
}
</code></pre>

</div>

<a class="anchor" id="subslice"></a>
<h3>Derive Slices From Arrays and Slices</h3>

<div>
<p>
We can derive a new slice from another (base) slice or a base addressable array
by using the subslice syntax forms (Go specification calls them as slice syntax forms).
The process is also often called as reslicing.
The elements of the derived slice and the base array or slice
are hosted on the same memory segment.
In other words, the derived slice and the base array or slice
may share some contiguous elements.
</p>

There are two subslice syntax forms (<code>baseContainer</code> is an array or slice):
<pre class="line-numbers"><code class="language-go">baseContainer[low : high]       // two-index form
baseContainer[low : high : max] // three-index form
</code></pre>

The two-index form is equivalent to
<pre class="disable-line-numbers111"><code class="language-go">baseContainer[low : high : cap(baseContainer)]
</code></pre>

<p>
So the two-index form is a special case of the three-index form.
The two-index form is used much more popularly
than the three-index form in practice.
</p>

<p>
Note, the three-index form is only supported since Go 1.2.
</p>

In a subslice expression, the <code>low</code>, <code>high</code> and
<code>max</code> indexes must satisfy the following relation requirements.

<pre class="disable-line-numbers111"><code class="language-go">// two-index form
0 <= low <= high <= cap(baseContainer)

// three-index form
0 <= low <= high <= max <= cap(baseContainer)
</code></pre>

<p>
Indexes not satisfying these requirements may make the subslice expression
fail to compile at compile time or panic at run time,
depending on the base container type kind and whether or not the indexes are constants.
</p>

Note,
<ul>
<li>
	the <code>low</code> and <code>high</code> indexes can be both larger than
	<code>len(baseContainer)</code>, as long as the above relations are all satisfied.
	But the two indexes must not be larger than <code>cap(baseContainer)</code>.
</li>
<li>
	a subslice expression will not cause a panic if <code>baseContainer</code>
	is a nil slice and all indexes used in the expression are zero.
	The result slice derived from a nil slice is still a nil slice.
</li>
</ul>

<p>
The length of the result derived slice is equal to <code>high - low</code>, and
the capacity of the result derived slice is equal to <code>max - low</code>.
The length of a derived slice may be larger than the base container,
but the capacity will never be larger than the base container.
</p>

In practice, for simplicity, we often omitted some indexes in subslice syntax forms.
The omission rules are:
<ul>
<li>
	if the <code>low</code> index is equal to zero, it can be omitted,
	either for two-index or three-index forms.
</li>
<li>
	if the <code>high</code> is equal to <code>len(baseContainer)</code>,
	it can be omitted, but only for two-index forms.
</li>
<li>
	the <code>max</code> can never be omitted in three-index forms.
</li>
</ul>

For example, the following expressions are equivalent.
<pre class="line-numbers"><code class="language-go">baseContainer[0 : len(baseContainer)]
baseContainer[: len(baseContainer)]
baseContainer[0 :]
baseContainer[:]
baseContainer[0 : len(baseContainer) : cap(baseContainer)]
baseContainer[: len(baseContainer) : cap(baseContainer)]
</code></pre>

An example of using subslice syntax forms:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	a := [...]int{0, 1, 2, 3, 4, 5, 6}
	s0 := a[:]     // <=> s0 := a[0:7:7]
	s1 := s0[:]    // <=> s1 := s0
	s2 := s1[1:3]  // <=> s2 := a[1:3]
	s3 := s1[3:]   // <=> s3 := s1[3:7]
	s4 := s0[3:5]  // <=> s4 := s0[3:5:7]
	s5 := s4[:2:2] // <=> s5 := s0[3:5:5]
	s6 := append(s4, 77)
	s7 := append(s5, 88)
	s8 := append(s7, 66)
	s3[1] = 99
	fmt.Println(len(s2), cap(s2), s2) // 2 6 [1 2]
	fmt.Println(len(s3), cap(s3), s3) // 4 4 [3 99 77 6]
	fmt.Println(len(s4), cap(s4), s4) // 2 4 [3 99]
	fmt.Println(len(s5), cap(s5), s5) // 2 2 [3 99]
	fmt.Println(len(s6), cap(s6), s6) // 3 4 [3 99 77]
	fmt.Println(len(s7), cap(s7), s7) // 3 4 [3 4 88]
	fmt.Println(len(s8), cap(s8), s8) // 4 4 [3 4 88 66]
}
</code></pre>

<p>
</p>

The following picture depicts the final memory layouts of the array
and slice values used in the above example.

<div class="text-center">
<img src="res/slice-subslice-2.png" alt="array and slice statuses"></img>
</div>

<p>
From the picture, we know that the elements of slice <code>s7</code> and <code>s8</code>
are hosted on a different underlying memory segment than the other containers.
The elements of the other slices are hosted on the same memory segment
hosting the array <code>a</code>.
</p>

Please note that, subslice operations may cause kind-of memory leaking.
For example, half of the memory allocated for the return slice of a call
to the following function will be wasted unless the returned slice becomes
unreachable (if no other slices share the underlying element memory segment with the returned slice).

<pre class="line-numbers"><code class="language-go">func f() []int {
	s := make([]int, 10, 100)
	return s[50:60]
}
</code></pre>

<p>
Please note that, in the above function,
the lower index (<code>50</code>) is larger than the length (<code>10</code>) of <code>s</code>,
which is allowed.
</p>

</div>

<a class="anchor" id="copy-slice-elements"></a>
<h3>Copy Slice Elements With the Built-in <code>copy</code> Function</h3>

<div>
<p>
We can use the built-in <code>copy</code> function to copy elements from one
slice to another, the types of the two slices are not required to be identical,
but their element types must be identical.
In other words, the two argument slices must share the same underlying type.
The first parameter of the <code>copy</code> function is the destination slice
and the second one is the source slice.
The two parameters can overlap some elements.
<code>copy</code> function returns the number of elements copied,
which will be the smaller one of the lengths of the two parameters.
</p>

<p>
With the help of the subslice syntax, we can use the <code>copy</code> function to
copy elements between two arrays or between an array and a slice.
</p>

An example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	type Ta []int
	type Tb []int
	dest := Ta{1, 2, 3}
	src := Tb{5, 6, 7, 8, 9}
	n := copy(dest, src)
	fmt.Println(n, dest) // 3 [5 6 7]
	n = copy(dest[1:], dest)
	fmt.Println(n, dest) // 2 [5 5 6]

	a := [4]int{} // an array
	n = copy(a[:], src)
	fmt.Println(n, a) // 4 [5 6 7 8]
	n = copy(a[:], a[2:])
	fmt.Println(n, a) // 2 [7 8 7 8]
}
</code></pre>

<p>
</p>

In fact, the <code>copy</code> function is not very essential.
We can implement it by using the built-in <code>append</code> function.

<pre class="line-numbers"><code class="language-go">// Assume element type is T.
func Copy(dest, src []T) int {
	if len(dest) < len(src) {
		_ = append(dest[:0], src[:len(dest)]...)
		return len(dest)
	} else {
		_ = append(dest[:0], src...)
		return len(src)
	}
}
</code></pre>

<p>
Although the <code>copy</code> function is not an essential function in Go,
for many circumstances, it is more convenient that the just shown way.
</p>

<p>
From another point of view, the <code>append</code> function can also be viewed
as a non-essential function (whereas <code>copy</code> is viewed as an
essential function), for all its uses can be implemented with
<code>make</code> and <code>copy</code> function calls.
</p>

<p>
Note, as a special case, the built-in <code>copy</code> function
can be used to <a href="string.html#use-string-as-byte-slice">copy bytes
from a string to a byte slice</a>.
</p>

<p>
Up to now (Go 1.13), neither of the two arguments of a <code>copy</code>
function call can be an untyped <code>nil</code> value.
</p>

</div>

<a class="anchor" id="iteration"></a>
<h3>Container Element Iterations</h3>

<div>

In Go, keys and elements of a container value can be iterated with
the following syntax:
<pre class="disable-line-numbers111"><code class="language-go">for key, element = range aContainer {
	// use key and element ...
}
</code></pre>

<p>
where <code>for</code> and <code>range</code> are two keywords,
<code>key</code> and <code>element</code> are called iteration variables.
If <code>aContainer</code> is a slice or an array (or an array pointer, see below),
then the type of <code>key</code> must be built-in type <code>int</code>.
</p>

<p>
The assignment sign <code>=</code> can be a short variable declaration sign
<code>:=</code>, in which case the two iteration variables are both two new declared
variables which are only visible within the <code>for-range</code> code block body,
if <code>aContainer</code> is a slice or an array (or an array pointer),
then the type of <code>key</code> is deduced as <code>int</code>.
</p>

<p>
Like the traditional <code>for</code> loop block, each <code>for-range</code>
loop block creates two code blocks, an implicit one and an explicit one
which is formed by using <code>{}</code>.
The explicit one is nested in the implicit one.
</p>

<p>
Like <code>for</code> loop blocks, <code>break</code> and <code>continue</code>
statements can also be used in <code>for-range</code> loop blocks,
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	m := map[string]int{"C": 1972, "C++": 1983, "Go": 2009}
	for lang, year := range m {
		fmt.Printf("%v: %v \n", lang, year)
	}

	a := [...]int{2, 3, 5, 7, 11}
	for i, prime := range a {
		fmt.Printf("%v: %v \n", i, prime)
	}

	s := []string{"go", "defer", "goto", "var"}
	for i, keyword := range s {
		fmt.Printf("%v: %v \n", i, keyword)
	}
}
</code></pre>

<p>
</p>

The form <code>for-range</code> code block syntax has several variants:
<pre class="line-numbers"><code class="language-go">// Ignore the key iteration variable.
for _, element = range aContainer {
	// ...
}

// Ignore the element iteration variable.
for key, _ = range aContainer {
	element = aContainer[key]
	// ...
}

// The element iteration variable is omitted.
// This form is equivalent to the last one.
for key = range aContainer {
	element = aContainer[key]
	// ...
}

// Ignore both the key and element iteration variables.
for _, _ = range aContainer {
	// This variant is not much useful.
}

// Both the key and element iteration variables are
// omitted. This form is equivalent to the last one.
for range aContainer {
	// This variant is not much useful.
}
</code></pre>

<p>
Iterating over nil maps or nil slices is allowed. Such iterations are no-ops.
</p>

Some details about iterations over maps are listed here.
<ul>
<li>
	For a map, the entry order in an iteration is not guaranteed to be the
	same as the next iteration, even if the map is not modified between
	the two iterations. By Go specification, the order is unspecified (kind-of randomized).
</li>
<li>
	If a map entry (a key-element pair) which has not yet been reached
	is removed during an iteration, then the entry will not
	iterated in the same iteration for sure.
</li>
<li>
	If a map entry is created during an iteration,
	that entry may be iterated during the same iteration, or not.
</li>
</ul>

If it is promised that there are no other goroutines
manipulating a map <code>m</code>, then the following code is guaranteed to
clear all entries stored in the map <code>m</code>:
<pre class="line-numbers"><code class="language-go">for key := range m {
	delete(m, key)
}
</code></pre>

<p>
</p>

Surely, array and slice elements can also be iterated by using the traditional <code>for</code> loop block:
<pre class="line-numbers"><code class="language-go">for i := 0; i < len(anArrayOrSlice); i++ {
	element := anArrayOrSlice[i]
	// ...
}
</code></pre>

<p>
</p>

For a <code>for-range</code> loop block

<pre class="disable-line-numbers111"><code class="language-go">for key, element = range aContainer {...}
</code></pre>

there are three important facts.

<ol>
<li>
	The ranged container is <b>a copy</b> of <code>aContainer</code>.
	Please note, <a href="value-part.html#about-value-copy">only
	the direct part of <code>aContainer</code> is copied</a>.
	The container copy is anonymous, so there are no ways to modify it.
	<ul>
	<li>
		If the <code>aContainer</code> is an array, then the
		modifications made on the array elements during the iteration
		will not be reflected to the iteration variables.
		The reason is that the copy of the array doesn't
		share elements with the array.
	</li>
	<li>
		If the <code>aContainer</code> is a slice or map, then the
		modifications made on the slice or map elements during
		the iteration will be reflected to the iteration variables.
		The reason is that the clone of the slice (or map)
		shares all elements (entries) with the slice (or map).
	</li>
	</ul>
</li>
<li>
	A key-element pair of the copy of <code>aContainer</code> will be
	assigned (copied) to the iteration variable pair at each iteration step,
	so the modifications made on <b>the direct parts</b>
	of the iteration variables will not be reflected to the elements
	(and keys for maps) stored in <code>aContainer</code>.
	(For this fact, and as using <code>for-range</code> loop blocks is the only way
	to iterate map keys and elements, it is recommended not to use large-size types
	as map key and element types, to avoid large copy burdens.)
</li>
<li>
	All key-element pairs will be assigned to the <b>same</b> iteration variable pair.
</li>
</ol>

An example which proves the first and second facts.

<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	type Person struct {
		name string
		age  int
	}
	persons := [2]Person {{"Alice", 28}, {"Bob", 25}}
	for i, p := range persons {
		fmt.Println(i, p)

		// This modification has no effects on
		// the iteration, for the ranged array
		// is a copy of the persons array.
		persons[1].name = "Jack"

		// This modification has not effects on
		// the persons array, for p is just a
		// copy of a copy of one persons element.
		p.age = 31
	}
	fmt.Println("persons:", &persons)
}
</code></pre>

The output:
<pre class="output"><code>0 {Alice 28}
1 {Bob 25}
persons: &[{Alice 28} {Jack 25}]
</code></pre>

<p>
</p>

If we change the array in the above to a slice, then the modification on the
slice during the iteration has effects on the iteration, but
the modification on the iteration variable still has no effects on the slice.

<pre class="line-numbers"><code class="language-go">...

	// A slice.
	persons := []Person {{"Alice", 28}, {"Bob", 25}}
	for i, p := range persons {
		fmt.Println(i, p)

		// Now this modification has effects
		// on the iteration.
		persons[1].name = "Jack"

		// This modification still has not
		// any real effects.
		p.age = 31
	}
	fmt.Println("persons:", &persons)
}
</code></pre>

The output becomes to:
<pre class="output"><code>0 {Alice 28}
1 {Jack 25}
persons: &[{Alice 28} {Jack 25}]
</code></pre>

<p>
</p>

An example to prove the second and third facts.
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	langs := map[struct{ dynamic, strong bool }]map[string]int{
		{true, false}:  {"JavaScript": 1995},
		{false, true}:  {"Go": 2009},
		{false, false}: {"C": 1972},
	}
	// The key type and element type of this map
	// are both pointer types. Some weird, just
	// for education purpose.
	m0 := map[*struct{ dynamic, strong bool }]*map[string]int{}
	for category, langInfo := range langs {
		m0[&category] = &langInfo
		// This following line has no effects on langs.
		category.dynamic, category.strong = true, true
	}
	for category, langInfo := range langs {
		fmt.Println(category, langInfo)
	}

	m1 := map[struct{ dynamic, strong bool }]map[string]int{}
	for category, langInfo := range m0 {
		m1[*category] = *langInfo
	}
	// m0 and m1 both contain only one entry.
	fmt.Println(len(m0), len(m1)) // 1 1
	fmt.Println(m1) // map[{true true}:map[C:1972]]
}
</code></pre>

As mentioned above, the entry iteration order is randomized,
so the order of the first three lines of the output of
the above program may be not same as the following one.

<pre class="output"><code>{false true} map[Go:2009]
{false false} map[C:1972]
{true false} map[JavaScript:1995]
1 1
map[{true true}:map[Go:2009]]
</code></pre>

<p>
</p>

<p>
The cost of a slice or map assignment is small, but the cost of an array assignment
is large if the size of the array type is large.
So, generally, it is not a good idea to range over a large array.
We can range over a slice derived from the array, or range over a pointer
to the array (see the next section for details).
</p>

For an array or slice, if the size of its element type is large, then,
generally, it is also not a good idea to use the second iteration variable to
store the iterated element at each loop step.
For such arrays and slices, we should use the one-iteration-variable
<code>for-range</code> loop variant or the traditional <code>for</code>
loop to iterate their elements.
In the following example, the loop in function <code>fa</code> is much less
efficient than the loop in function <code>fb</code>.

<pre class="line-numbers"><code class="language-go">type Buffer struct {
	start, end int
	data       [1024]byte
}

func fa(buffers []Buffer) int {
	numUnreads := 0
	for _, buf := range buffers {
		numUnreads += buf.end - buf.start
	}
	return numUnreads
}

func fb(buffers []Buffer) int {
	numUnreads := 0
	for i := range buffers {
		numUnreads += buffers[i].end - buffers[i].start
	}
	return numUnreads
}
</code></pre>

<p>
</p>

</div>

<a class="anchor" id="use-pointer-as-array"></a>
<h3>Use Array Pointers as Arrays</h3>

<div>
<p>
In many scenarios, we can use a pointer to an array as the array.
</p>

We can range over a pointer to an array to iterate the elements of the array.
For arrays with large lengths, this way is much more efficient, for copying
a pointer is much more efficient than copying a large-size array.
In the following example, the two loop blocks are equivalent
and both are efficient.
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	var a [100]int

	// Copying a pointer is cheap.
	for i, n := range &a {
		fmt.Println(i, n)
	}

	// Copying a slice is cheap.
	for i, n := range a[:] {
		fmt.Println(i, n)
	}
}
</code></pre>

<p>
</p>

If the second iteration in a <code>for-range</code> loop is neither ignored nor omitted,
then range over a nil array pointer will panic.
In the following example, each of the first two loop
blocks will print five indexes, however, the last one will produce a panic.

<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	var p *[5]int // nil

	for i, _ := range p { // okay
		fmt.Println(i)
	}

	for i := range p { // okay
		fmt.Println(i)
	}

	for i, n := range p { // panic
		fmt.Println(i, n)
	}
}
</code></pre>

<p>
</p>

Array pointers can also used to index array elements.
Indexing array elements through a nil array pointer produces a panic.
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	a := [5]int{2, 3, 5, 7, 11}
	p := &a
	p[0], p[1] = 17, 19
	fmt.Println(a) // [17 19 5 7 11]
	p = nil
	_ = p[0] // panic
}
</code></pre>

<p>
</p>

We can also derive slices from array pointers.
Deriving slices from a nil array pointer produce a panic.

<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	pa := &[5]int{2, 3, 5, 7, 11}
	s := pa[1:3]
	fmt.Println(s) // [3 5]
	pa = nil
	s = pa[0:0] // panic
}
</code></pre>

<p>
</p>

We can also pass array pointers as the arguments of the built-in
<code>len</code> and <code>cap</code> functions.
Nil array pointer arguments for the two functions will not produce panics.

<pre class="line-numbers"><code class="language-go">var pa *[5]int // == nil
fmt.Println(len(pa), cap(pa)) // 5 5
</code></pre>

<p>
</p>

</div>

<a class="anchor" id="memclr"></a>
<h3>The <code>memclr</code> Optimization</h3>

<div>
Assume <code>t0</code> is a literal presentation of the zero value of
type <code>T</code>, and <code>a</code> is an array which element type is
<code>T</code>, then the standard Go compiler will translate the following
one-iteration-variable <code>for-range</code> loop block
<pre class="line-numbers"><code class="language-go">for i := range a {
	a[i] = t0
}
</code></pre>
<p>
to an <a href="https://github.com/golang/go/issues/5373">internal
<code>memclr</code> call</a>, generally which is faster
than resetting each element one by one.
</p>

<p>
The optimization was adopted in the standard Go compiler 1.5.
</p>

The optimization also works if the ranged container is a slice. Sadly,
it doesn't work if the ranged value is an array pointer (up to Go 1.12).
So if you want to reset an array, don't range its pointer. In particular,
it is recommended to range a slice derived from the array, like this:

<pre class="line-numbers"><code class="language-go">s := a[:]
for i := range s {
	s[i] = t0
}
</code></pre>

<p>
The reason of why it is not recommended to range over the array directly is
it is very possible that other Go compilers don't make the above optimization,
and as above has mentioned, ranging over the array will make a copy
of the array (though the standard Go compiler won't in this optimization).
</p>

</div>

<a class="anchor" id="compile-time-evaluation"></a>
<h3>Calls to the Built-in <code>len</code> and <code>cap</code> Functions May Be Evaluated at Compile Time</h3>

<div>
<p>
If the argument passed to a built-in function <code>len</code> or
<code>cap</code> function call is an array or an array pointer value,
then the call is evaluated at compile time and the result of the call
is a typed constant with type as the built-in type <code>int</code>.
The result can be bound to named constants.
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

var a [5]int
var p *[7]string

// N and M are both typed constants.
const N = len(a)
const M = cap(p)

func main() {
	fmt.Println(N) // 5
	fmt.Println(M) // 7
}
</code></pre>

<p>
</p>
</div>

<a class="anchor" id="modify-slice-length-and-capacity"></a>
<h3>Modify the Length and Capacity Properties of a Slice Individually</h3>

<div>
<p>
Above has mentioned, generally, the length and capacity of
a slice value can't be modified individually.
A slice value can only be overwritten as a whole
by assigning another slice value to it.
However, we can modify the length and capacity of a slice
individually by using reflections.
Reflection will be explained in <a href="reflection.html">a later article</a> in detail.
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import (
	"fmt"
	"reflect"
)

func main() {
	s := make([]int, 2, 6)
	fmt.Println(len(s), cap(s)) // 2 6

	reflect.ValueOf(&s).Elem().SetLen(3)
	fmt.Println(len(s), cap(s)) // 3 6

	reflect.ValueOf(&s).Elem().SetCap(5)
	fmt.Println(len(s), cap(s)) // 3 5
}
</code></pre>

<p>
The second argument passed to the <code>reflect.SetLen</code> function must not
be larger than the current capacity of the argument slice <code>s</code>.
The second argument passed to the <code>reflect.SetCap</code> function must not
be smaller than the current length of the argument slice <code>s</code> and
larger than the current capacity of the argument slice <code>s</code>.
Otherwise, a panic will occur.
</p>

<p>
The reflection way is very inefficient, it is slower than a slice assignment.
</p>
</div>

<a class="anchor" id="slice-manipulations"></a>
<h3>More Slice Manipulations</h3>

<p>
Go doesn't support more built-in slice operations,
such as slice clone, element deletion and insertion.
We must compose the built-in ways to achieve those operations.
</p>

<p>
In the following examples in the current section,
assume <code>s</code> is the talked slice,
<code>T</code> is its element type and <code>t0</code>
is a zero value literal representation of <code>T</code>.
</p>

<h4>Clone Slices</h4>

<div>
For the latest standard Go compler (version 1.12), the simplest way to clone a slice is:
<pre class="disable-line-numbers111"><code class="language-go">sClone := append(s[:0:0], s...)
</code></pre>

For slices with large lengths (thousands of elements),
the above way is more efficient than
<pre class="disable-line-numbers111"><code class="language-go">sClone := make([]T, len(s))
copy(sClone, s)
</code></pre>

<p>
The second way has a drawback that
if <code>s</code> is a nil slice, the second way results a non-nil clone.
</p>

</div>

<a class="anchor" id="delete-slice-elements"></a>
<h4>Delete a segment of slice elements</h4>

<div>
Above has mentioned that the elements a slice are stored contiguously
in memory and there are no gaps between any two adjacent elements of the slice.
So when a slice element is removed,
<ul>
<li>
	if the element order must be preserved,
	then each of the subsequent elements followed the removed elements
	must be moved forwards.
</li>
<li>
	if the element order doesn't need to be preserved,
	then we can move the last elements in the slice to the removed indexes.
</li>
</ul>

In the following example, assume <code>from</code> and <code>to</code> are
two legal indexes, <code>from</code> is not larger than <code>to</code>,
and the <code>to</code> index is exclusive.
<pre class="line-numbers"><code class="language-go">// way 1 (preserve element orders):
s = append(s[:from], s[to:]...)

// way 2 (preserve element orders):
s = s[:from + copy(s[from:], s[to:])]

// Don't preserve element orders:
if n := to-from; len(s)-to < n {
	copy(s[from:to], s[to:])
} else {
	copy(s[from:to], s[len(s)-n:])
}
s = s[:len(s)-(to-from)]
</code></pre>

If the slice elements reference other values, we should reset
tail elements (on the just freed-up slots) to avoid memory leaking.

<pre class="line-numbers"><code class="language-go">// "len(s)+to-from" is the old slice length.
temp := s[len(s):len(s)+to-from]
for i := range temp {
	temp[i] = t0
}
</code></pre>

<p>
As mentioned above, the <code>for-range</code> loop code block will be
optimized as a <code>memclr</code> call by the standard Go compiler.
</p>

</div>

<a class="anchor" id="delete-one-slice-element"></a>
<h4>Delete one slice element</h4>

<div>
<p>
Deleting one element is similar to, and also simpler than,
deleting a segment of elements.
</p>

In the following example,
assume <code>i</code> the index of the element to be removed
and <code>i</code> is a legal index.

<pre class="line-numbers"><code class="language-go">// Way 1 (preserve element orders):
s = append(s[:i], s[i+1:]...)

// Way 2 (preserve element orders):
s = s[:i + copy(s[i:], s[i+1:])]

// There will be len(s)-i-1 elements being
// copied in either of the above two ways.

// Don't preserve element orders:
s[i] = s[len(s)-1]
s = s[:len(s)-1]
</code></pre>

<p>
</p>

If the slice elements contain pointers, then after the deletion action,
we should reset the last element of the old slice value
to avoid memory leaking:
<pre class="line-numbers"><code class="language-go">s[len(s):len(s)+1][0] = t0
// or
s[:len(s)+1][len(s)] = t0
</code></pre>

<p>
</p>
</div>

<h4>Delete slice elements conditionally</h4>

<div>
Sometimes, we may need to delete slice elements by some conditions.

<pre class="line-numbers"><code class="language-go">// Assume T is a small-size type.
func DeleteElements(s []T, keep func(T) bool, clear bool) []T {
	//result := make([]T, 0, len(s))
	result := s[:0] // without allocating a new slice
	for _, v := range s {
		if keep(v) {
			result = append(result, v)
		}
	}
	if clear { // avoid memory leaking
		temp := s[len(result):]
		for i := range temp {
			// t0 is a zero value literal of T.
			temp[i] = t0
		}
	}
	return result
}
</code></pre>

<p>
Please note, if <code>T</code> is not a small-size type, then generally
we should <a href="value-copy-cost.html#copy-costs">try to</a> avoid
using <code>T</code> as function parameter types and using two-iteration-variable
<code>for-range</code> block form to iterate slices with element types as <code>T</code>.
</p>

</div>

<h4>Insert all elements of a slice into another slice</h4>

<div>
Assume the insertion position is a legal index <code>i</code>
and <code>elements</code> is the slice whose elements are to be inserted.

<pre class="line-numbers"><code class="language-go">// One-line implementation:
s = append(s[:i], append(elements, s[i:]...)...)

// A more efficient but more verbose way:
if cap(s)-len(s) >= len(elements) {
	s = s[:len(s)+len(elements)]
	copy(s[i+len(elements):], s[i:])
	copy(s[i:], elements)
} else {
	x := make([]T, 0, len(elements)+len(s))
	x = append(x, s[:i]...)
	x = append(x, elements...)
	x = append(x, s[i:]...)
	s = x
}

// Push:
s = append(s, elements...)

// Unshift:
s = append(elements, s...)
</code></pre>

<p>
The <code>make</code> call in the above code snippet clear the memory allocated for for slice <code>x</code>,
this is actually an unnecessary operation for this specified use case.
<a href="https://github.com/golang/go/issues/31592">Future compiler optimization</a> might remove the clear operation.
</p>

</div>

<h4>Insert several individual elements</h4>

<p>
Inserting several individual elements is similar to inserting all elements of a slice.
We can construct a slice with a slice composite literal with the elements
to be inserted, then use the above ways to insert these elements.
</p>

<h4>Special eeletions and insertions: push front/back, pop front/back</h4>

<div>
Assume the pushed or popped element is <code>e</code> and slice
<code>s</code> has at least one element.

<pre class="line-numbers"><code class="language-go">// Pop front (shift):
s, e = s[1:], s[0]
// Pop back:
s, e = s[:len(s)-1], s[len(s)-1]
// Push front:
s = append([]T{e}, s...)
// Push back:
s = append(s, e)
</code></pre>

<p>
</p>
</div>

<h4>More slice operations</h4>

<p>
In reality, the needs are varied.
For some specific cases, it is possible none of the above ways shown
in the above examples are the most efficient way. And sometimes,
the above ways may not satisfy some specific requirements in practice.
So, please learn and apply elastically.
This may be the reason why Go doesn't support the more operations
introduced above in the built-in way.
</p>

<h3>Use Maps to Simulate Sets</h3>

<p>
Go doesn't support built-in <b>set</b> types.
However, it is easy to use a map type to simulate a set type.
In practice, we often use the map type <code>map[K]struct{}</code>
to simulate a set type with element type <code>K</code>.
The size of the map element type <code>struct{}</code> is zero,
elements of values of such map types don't occupy memory space.
</p>

<h3>Container Related Operations Are Not Synchronized Internally</h3>

<p>
Please note that, all container operations are not synchronized internally.
Without making using of any data synchronization technique,
it is okay for multiple goroutines to read a container concurrently,
but it is not okay for multiple goroutines to manipulate a container
concurrently and at least one goroutine modifies the container.
The latter case will cause data races, even make goroutines panic.
We must synchronize the container operations manually.
Please read the articles on
<a href="concurrent-synchronization-overview.html">data synchronizations</a>
for details.
</p>












